import requests
from lxml import etree
import json
class Music2t58:
    def __init__(self):
        self.url = "https://www.2t58.com/"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
        }

    def home(self):
        """获取首页数据"""
        try:
            response = requests.get(self.url, headers=self.headers)
            response.encoding = 'utf-8'
            html = etree.HTML(response.text)
            
            # 获取热门歌手
            singers = []
            singer_elements = html.xpath('//div[@class="lksinger_list"]//li')
            for singer in singer_elements:
                try:
                    name = singer.xpath('.//div[@class="name"]/a/text()')[0].strip()
                    link = singer.xpath('.//div[@class="name"]/a/@href')[0]
                    # 从链接中提取歌手ID
                    singer_id = link.split('/')[-1].replace('.html', '')
                    img = singer.xpath('.//div[@class="pic"]/a/img/@src')[0]
                    singers.append({
                        'name': name,
                        'id': singer_id,  # 添加歌手ID
                        'link': self.url + link.lstrip('/'),
                        'img': img
                    })
                except Exception as e:
                    print(f"解析歌手数据出错: {str(e)}")
                    continue

            # 获取热门歌单
            playlists = []
            playlist_elements = html.xpath('//div[@class="ilingku_list"]//li')
            for playlist in playlist_elements[:10]:  # 只取前10个歌单
                try:
                    name = playlist.xpath('.//div[@class="name"]/a/text()')[0].strip()
                    link = playlist.xpath('.//div[@class="name"]/a/@href')[0]
                    # 从链接中提取歌单ID
                    playlist_id = link.split('/')[-1].replace('.html', '')
                    img = playlist.xpath('.//div[@class="pic"]/a/img/@src')[0]
                    playlists.append({
                        'name': name,
                        'id': playlist_id,  # 添加歌单ID
                        'link': self.url + link.lstrip('/'),
                        'img': img
                    })
                except Exception as e:
                    print(f"解析歌单数据出错: {str(e)}")
                    continue

            # 获取音乐列表
            songs = []
            song_elements = html.xpath('//div[@class="ilingkuplay_list"]//li')
            for song in song_elements:
                try:
                    # 获取歌曲名和链接
                    name = song.xpath('.//div[@class="name"]/a/text()')[0].strip()
                    link = song.xpath('.//div[@class="name"]/a/@href')[0]
                    # 从链接中提取歌曲ID
                    song_id = link.split('/')[-1].replace('.html', '')
                    
                    # 检查是否有MV
                    mv_link = song.xpath('.//div[@class="mv"]/a/@href')
                    mv_url = self.url + mv_link[0].lstrip('/') if mv_link else None
                    
                    songs.append({
                        'name': name,
                        'id': song_id,  # 添加歌曲ID
                        'link': self.url + link.lstrip('/'),
                        'mv_url': mv_url
                    })
                except Exception as e:
                    print(f"解析歌曲数据出错: {str(e)}")
                    continue

            # 获取更新时间
            update_time = html.xpath('//div[@class="pagedata"]/span/text()')
            update_time = update_time[0] if update_time else None

            return {
                'singers': singers,  # 热门歌手
                'playlists': playlists,  # 热门歌单
                'songs': songs,  # 音乐列表
                'update_time': update_time  # 更新时间
            }
            
        except Exception as e:
            print(f"获取首页数据出错: {str(e)}")
            return None

    def get_singer_songs(self, singer_id):
        """获取歌手的所有歌曲"""
        try:
            url = f"{self.url}/singer/{singer_id}.html"
            response = requests.get(url, headers=self.headers)
            response.encoding = 'utf-8'
            html = etree.HTML(response.text)
            
            # 获取歌手信息
            singer_info = {
                'id': singer_id,  # 添加歌手ID
                'name': html.xpath('//div[@class="list_r"]/h1/text()')[0].strip(),
                'avatar': html.xpath('//div[@class="pic"]/img/@src')[0],
                'desc': html.xpath('//div[@class="info"]/p/text()')[0].strip()
            }
            
            # 获取歌曲列表
            songs = []
            song_elements = html.xpath('//div[@class="play_list"]//li')
            for song in song_elements:
                try:
                    name = song.xpath('.//div[@class="name"]/a/text()')[0].strip()
                    link = song.xpath('.//div[@class="name"]/a/@href')[0]
                    # 从链接中提取歌曲ID
                    song_id = link.split('/')[-1].replace('.html', '')
                    
                    # 检查是否有MV
                    mv_link = song.xpath('.//div[@class="mv"]/a/@href')
                    mv_url = self.url + mv_link[0].lstrip('/') if mv_link else None
                    
                    songs.append({
                        'name': name,
                        'id': song_id,  # 添加歌曲ID
                        'link': self.url + link.lstrip('/'),
                        'mv_url': mv_url
                    })
                except Exception as e:
                    print(f"解析歌曲数据出错: {str(e)}")
                    continue
            
            # 获取分页信息
            pagination = {}
            try:
                # 获取当前页码
                current_page = html.xpath('//div[@class="page"]/a[@class="current"]/text()')[0]
                # 获取总页数
                last_page_link = html.xpath('//div[@class="page"]/a[@class="lkpc"]/@href')[0]
                total_pages = last_page_link.split('/')[-1].replace('.html', '')
                
                pagination = {
                    'current_page': int(current_page),
                    'total_pages': int(total_pages),
                    'has_next': False,
                    'next_page': None,
                    'has_prev': False,
                    'prev_page': None
                }
                
                # 检查是否有下一页
                next_link = html.xpath('//div[@class="page"]/a[text()="下一页"]')
                if next_link:
                    pagination['has_next'] = True
                    pagination['next_page'] = int(current_page) + 1
                
                # 检查是否有上一页
                if int(current_page) > 1:
                    pagination['has_prev'] = True
                    pagination['prev_page'] = int(current_page) - 1
                    
            except Exception as e:
                print(f"获取分页信息出错: {str(e)}")
                
            return {
                'singer': singer_info,
                'songs': songs,
                'pagination': pagination
            }
            
        except Exception as e:
            print(f"获取歌手歌曲列表出错: {str(e)}")
            return None

    def get_song_detail(self, song_id):
        """获取歌曲详情(包含音乐文件和歌词)"""
        try:
            # 获取音乐数据
            music_api = f"{self.url}/js/play.php"
            data = {
                'id': song_id,
                'type': 'music'
            }
            
            # 添加必要的请求头
            headers = {
                **self.headers,
                'Content-Type': 'application/x-www-form-urlencoded',
                'Referer': self.url,
                'X-Requested-With': 'XMLHttpRequest'
            }
            
            # 发送请求并检查响应
            response = requests.post(music_api, headers=headers, data=data)
            response.raise_for_status()  # 检查HTTP错误
            
            try:
                music_data = response.json()
            except json.JSONDecodeError:
                print(f"音乐数据解析失败，响应内容: {response.text[:200]}")  # 只打印前200个字符
                return None
            
            if music_data.get('msg') != 1:
                print(f"获取音乐数据失败，返回信息: {music_data}")
                return None
            
            # 获取歌词数据
            lrc_api = "https://js.eev3.com/lrc.php"
            params = {
                'cid': music_data.get('lkid')
            }
            
            try:
                lrc_response = requests.get(lrc_api, headers=self.headers, params=params)
                lrc_response.raise_for_status()
                lrc_data = lrc_response.json()
            except Exception as e:
                print(f"获取歌词失败: {str(e)}")
                lrc_data = {'lrc': ''}  # 使用空歌词继续
            
            # 解析歌词文本
            lrc_lines = []
            if lrc_data.get('lrc'):
                for line in lrc_data['lrc'].split('\n'):
                    if line.strip() and '[' in line:
                        try:
                            time_str = line[line.find('[')+1:line.find(']')]
                            text = line[line.find(']')+1:].strip()
                            
                            # 转换时间为秒数
                            if ':' in time_str:
                                m, s = time_str.split(':')
                                timestamp = float(m) * 60 + float(s)
                            else:
                                timestamp = float(time_str)
                                
                            if text:  # 只添加有文本的歌词行
                                lrc_lines.append({
                                    'time': timestamp,
                                    'text': text
                                })
                        except Exception as e:
                            print(f"解析歌词行失败: {line}, 错误: {str(e)}")
                            continue
            
            result = {
                'title': music_data.get('title'),
                'cover': music_data.get('pic'),
                'audio_url': music_data.get('url'),
                'lyrics': {
                    'raw': lrc_data.get('lrc'),
                    'parsed': sorted(lrc_lines, key=lambda x: x['time'])
                }
            }
            
            # 验证必要字段
            if not result['audio_url']:
                print("未获取到音频URL")
                return None
            
            return result
            
        except requests.RequestException as e:
            print(f"网络请求错误: {str(e)}")
            return None
        except Exception as e:
            print(f"获取歌曲详情出错: {str(e)}")
            return None

    def search_music(self, keyword, page=1):
        """搜索音乐
        
        Args:
            keyword: 搜索关键词
            page: 页码，默认1
            
        Returns:
            dict: 包含搜索结果和分页信息
        """
        try:
            # URL编码搜索关键词
            encoded_keyword = requests.utils.quote(keyword)
            url = f"{self.url}/so/{encoded_keyword}"
            if page > 1:
                url = f"{url}/{page}.html"
            else:
                url = f"{url}.html"
            response = requests.get(url, headers=self.headers)
            response.encoding = 'utf-8'
            html = etree.HTML(response.text)
            
            # 获取搜索结果总数
            total_count = 0
            count_text = html.xpath('//div[@class="pagedata"]/span/text()')
            if count_text:
                try:
                    total_count = int(count_text[0])
                except:
                    pass
            
            # 获取音乐列表
            songs = []
            song_elements = html.xpath('//div[@class="play_list"]//li')
            for song in song_elements:
                try:
                    # 获取歌曲名和链接
                    name = song.xpath('.//div[@class="name"]/a/text()')[0].strip()
                    link = song.xpath('.//div[@class="name"]/a/@href')[0]
                    song_id = link.split('/')[-1].replace('.html', '')
                    
                    # 检查是否有MV
                    mv_link = song.xpath('.//div[@class="mv"]/a/@href')
                    mv_url = self.url + mv_link[0].lstrip('/') if mv_link else None
                    
                    songs.append({
                        'name': name,
                        'id': song_id,
                        'link': self.url + link.lstrip('/'),
                        'mv_url': mv_url
                    })
                except Exception as e:
                    print(f"解析歌曲数据出错: {str(e)}")
                    continue
            
            # 获取分页信息
            pagination = {}
            try:
                # 获取当前页码
                current_page = html.xpath('//div[@class="page"]/a[@class="current"]/text()')[0]
                # 获取总页数
                last_page_link = html.xpath('//div[@class="page"]/a[last()]/@href')[0]
                total_pages = last_page_link.split('/')[-1].replace('.html', '')
                
                pagination = {
                    'current_page': int(current_page),
                    'total_pages': int(total_pages),
                    'has_next': False,
                    'next_page': None,
                    'has_prev': False,
                    'prev_page': None,
                    'total_count': total_count  # 搜索结果总数
                }
                
                # 检查是否有下一页
                next_link = html.xpath('//div[@class="page"]/a[text()="下一页"]')
                if next_link:
                    pagination['has_next'] = True
                    pagination['next_page'] = int(current_page) + 1
                
                # 检查是否有上一页
                if int(current_page) > 1:
                    pagination['has_prev'] = True
                    pagination['prev_page'] = int(current_page) - 1
                    
            except Exception as e:
                print(f"获取分页信息出错: {str(e)}")
                pagination = {
                    'current_page': 1,
                    'total_pages': 1,
                    'has_next': False,
                    'next_page': None,
                    'has_prev': False,
                    'prev_page': None,
                    'total_count': total_count
                }
            
            # 获取热门搜索词
            hot_searches = []
            hot_elements = html.xpath('//div[@class="hot_search_box"]//a')
            for hot in hot_elements:
                try:
                    keyword = hot.xpath('.//span/text()')[0].strip()
                    link = hot.xpath('./@href')[0]
                    hot_searches.append({
                        'keyword': keyword,
                        'link': self.url + link.lstrip('/')
                    })
                except:
                    continue
                
            return {
                'songs': songs,
                'pagination': pagination,
                'hot_searches': hot_searches
            }
            
        except Exception as e:
            print(f"搜索音乐出错: {str(e)}")
            return None

if __name__ == "__main__":
    music = Music2t58()
    print(music.get_song_detail("d213d2R4aw"))

    


